package com.axing.aiguideagent.tools;


import cn.hutool.core.io.FileUtil;
import com.axing.aiguideagent.constant.FileConstant;
import com.itextpdf.kernel.colors.ColorConstants;
import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.Paragraph;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.tool.annotation.Tool;
import org.springframework.ai.tool.annotation.ToolParam;

import java.io.IOException;

/**
 * PDF生成工具
 * 支持中文内容生成，包含基本的格式化功能
 */
@Slf4j
public class PDFGenerationTool {

    @Tool(description = "Generate a PDF file with given content. Supports Chinese characters and basic formatting with Markdown-like syntax.")
    public String generatePDF(
            @ToolParam(description = "Name of the file to save the generated PDF (should end with .pdf)") String fileName,
            @ToolParam(description = "Content to be included in the PDF. Supports line breaks and basic text.") String content) {
        
        // 确保文件名以.pdf结尾
        if (!fileName.toLowerCase().endsWith(".pdf")) {
            fileName += ".pdf";
        }
        
        String fileDir = FileConstant.FILE_SAVE_DIR + "/pdf";
        String filePath = fileDir + "/" + fileName;
        
        try {
            // 创建目录
            FileUtil.mkdir(fileDir);
            log.info("正在生成PDF文件: {}", filePath);
            
            // 第一步：过滤掉非BMP字符和特殊符号
            String sanitizedContent = filterNonBMPCharacters(content);
            
            // 第二步：进一步清理，只保留最安全的字符
            sanitizedContent = deepCleanContent(sanitizedContent);
            
            if (sanitizedContent.trim().isEmpty()) {
                log.warn("过滤后内容为空，使用默认内容");
                sanitizedContent = "PDF内容包含不支持的特殊字符，已被过滤。\n\n原始内容长度: " + content.length() + " 字符";
            }
            
            // 创建 PdfWriter 和 PdfDocument 对象
            try (PdfWriter writer = new PdfWriter(filePath);
                 PdfDocument pdf = new PdfDocument(writer);
                 Document document = new Document(pdf)) {
                
                // 使用支持中文的字体
                PdfFont font = createChineseFont();
                PdfFont boldFont = createChineseBoldFont();
                
                if (font == null) {
                    log.error("无法创建中文字体");
                    return "Error: Unable to create Chinese font for PDF";
                }
                
                document.setFont(font);
                
                // 处理内容并添加到文档
                processAndAddContent(document, sanitizedContent, font, boldFont);
                
                log.info("PDF文件生成成功: {}", filePath);
            }
            
            // 返回结构化信息，方便前端解析
            // 注意：不使用emoji，因为deepCleanContent会过滤掉它们
            return String.format("PDF文件生成成功\n\n文件名: %s\n保存路径: %s\n\n您可以点击下方卡片查看或下载PDF文件。", 
                    fileName, filePath);
        } catch (IOException e) {
            log.error("生成PDF时发生IO错误", e);
            return "生成PDF失败: " + e.getMessage();
        } catch (Exception e) {
            log.error("生成PDF时发生未知错误", e);
            return "生成PDF失败: " + e.getMessage();
        }
    }
    
    /**
     * 过滤掉非BMP字符和不支持的特殊字符
     * BMP (Basic Multilingual Plane) 包含 U+0000 到 U+FFFF 范围的字符
     * 超出此范围的字符（如emoji）会导致 STSongStd-Light 字体编码错误
     */
    private String filterNonBMPCharacters(String content) {
        if (content == null || content.isEmpty()) {
            return content;
        }
        
        StringBuilder filtered = new StringBuilder();
        int removedCount = 0;
        
        for (int i = 0; i < content.length(); i++) {
            char c = content.charAt(i);
            
            // 检查是否是高位代理（surrogate pair的开始）
            if (Character.isHighSurrogate(c)) {
                // 跳过整个代理对（通常是emoji或其他非BMP字符）
                if (i + 1 < content.length() && Character.isLowSurrogate(content.charAt(i + 1))) {
                    i++; // 跳过低位代理
                    removedCount++;
                }
                continue;
            }
            
            // 检查是否是低位代理（不应该单独出现）
            if (Character.isLowSurrogate(c)) {
                removedCount++;
                continue;
            }
            
            // 过滤掉特殊符号范围（可能导致字形问题）
            int codePoint = (int) c;
            
            // 跳过控制字符（除了常见的空白字符）
            if (Character.isISOControl(c) && c != '\n' && c != '\r' && c != '\t') {
                removedCount++;
                continue;
            }
            
            // 跳过一些已知会导致问题的Unicode范围
            // 各种符号和装饰字符（可能字体不支持）
            if ((codePoint >= 0x2600 && codePoint <= 0x27BF) ||  // 杂项符号
                (codePoint >= 0x2B50 && codePoint <= 0x2BFF) ||  // 杂项符号和箭头
                (codePoint >= 0x1F300 && codePoint <= 0x1F6FF) || // 杂项符号和象形文字
                (codePoint >= 0xFE00 && codePoint <= 0xFE0F) ||   // 变体选择器
                (codePoint >= 0xE0000 && codePoint <= 0xE007F)) { // 标签
                removedCount++;
                continue;
            }
            
            // 保留安全的字符范围
            // 基本拉丁字母、中日韩字符、常用标点符号等
            filtered.append(c);
        }
        
        if (removedCount > 0) {
            log.info("过滤了 {} 个不支持的字符", removedCount);
        }
        
        return filtered.toString();
    }
    
    /**
     * 深度清理内容，只保留最安全的字符
     * 包括：基本拉丁字母、数字、中文、日文、韩文、常见标点符号
     */
    private String deepCleanContent(String content) {
        if (content == null || content.isEmpty()) {
            return content;
        }
        
        StringBuilder cleaned = new StringBuilder();
        int removedCount = 0;
        
        for (char c : content.toCharArray()) {
            boolean isSafe = false;
            int codePoint = (int) c;
            
            // 基本拉丁字母、数字、标点 (U+0020 - U+007E)
            if (codePoint >= 0x0020 && codePoint <= 0x007E) {
                isSafe = true;
            }
            // 换行、回车、制表符
            else if (c == '\n' || c == '\r' || c == '\t') {
                isSafe = true;
            }
            // 中日韩统一表意文字 (U+4E00 - U+9FFF)
            else if (codePoint >= 0x4E00 && codePoint <= 0x9FFF) {
                isSafe = true;
            }
            // 中日韩兼容表意文字 (U+3400 - U+4DBF)
            else if (codePoint >= 0x3400 && codePoint <= 0x4DBF) {
                isSafe = true;
            }
            // 中文标点符号 (U+3000 - U+303F)
            else if (codePoint >= 0x3000 && codePoint <= 0x303F) {
                isSafe = true;
            }
            // 全角ASCII、全角标点 (U+FF00 - U+FFEF)
            else if (codePoint >= 0xFF00 && codePoint <= 0xFFEF) {
                isSafe = true;
            }
            // 日文平假名 (U+3040 - U+309F)
            else if (codePoint >= 0x3040 && codePoint <= 0x309F) {
                isSafe = true;
            }
            // 日文片假名 (U+30A0 - U+30FF)
            else if (codePoint >= 0x30A0 && codePoint <= 0x30FF) {
                isSafe = true;
            }
            // 韩文音节 (U+AC00 - U+D7AF)
            else if (codePoint >= 0xAC00 && codePoint <= 0xD7AF) {
                isSafe = true;
            }
            // 拉丁文扩展 (U+00A0 - U+00FF)
            else if (codePoint >= 0x00A0 && codePoint <= 0x00FF) {
                isSafe = true;
            }
            // 常用符号和箭头 (U+2190 - U+21FF) - 部分安全的
            else if (codePoint >= 0x2190 && codePoint <= 0x21FF) {
                isSafe = true;
            }
            // 数学运算符 (U+2200 - U+22FF) - 部分安全的
            else if (codePoint >= 0x2200 && codePoint <= 0x22FF) {
                isSafe = true;
            }
            
            if (isSafe) {
                cleaned.append(c);
            } else {
                removedCount++;
                log.debug("移除不安全字符: U+{} ({})", Integer.toHexString(codePoint).toUpperCase(), c);
            }
        }
        
        if (removedCount > 0) {
            log.info("深度清理移除了 {} 个潜在问题字符", removedCount);
        }
        
        return cleaned.toString();
    }
    
    /**
     * 创建支持中文的字体
     */
    private PdfFont createChineseFont() {
        try {
            // 尝试使用 font-asian 库中的字体
            return PdfFontFactory.createFont("STSongStd-Light", "UniGB-UCS2-H", PdfFontFactory.EmbeddingStrategy.PREFER_EMBEDDED);
        } catch (IOException e) {
            log.warn("无法加载STSongStd-Light字体，尝试备用方案", e);
            try {
                // 备用方案：尝试使用系统字体
                return PdfFontFactory.createFont("STSong-Light", "UniGB-UCS2-H", PdfFontFactory.EmbeddingStrategy.PREFER_EMBEDDED);
            } catch (IOException e2) {
                log.error("无法加载备用中文字体", e2);
                return null;
            }
        }
    }
    
    /**
     * 创建加粗的中文字体
     * 注意：由于 font-asian 库中的宋体没有专门的加粗版本，
     * 这里返回同样的字体，通过增大字号来模拟加粗效果
     */
    private PdfFont createChineseBoldFont() {
        try {
            // 尝试使用加粗字体，如果没有则返回普通字体
            return PdfFontFactory.createFont("STSongStd-Light", "UniGB-UCS2-H", PdfFontFactory.EmbeddingStrategy.PREFER_EMBEDDED);
        } catch (IOException e) {
            log.warn("无法加载加粗字体，将使用普通字体", e);
            return null;
        }
    }
    
    /**
     * 处理内容并添加到文档
     * 支持简单的格式化：
     * - 标题（以 # 开头）
     * - 空行分段
     * - 列表（以 - 或 数字. 开头）
     */
    private void processAndAddContent(Document document, String content, PdfFont normalFont, PdfFont boldFont) {
        if (content == null || content.isEmpty()) {
            document.add(new Paragraph("（空内容）"));
            return;
        }
        
        String[] lines = content.split("\n");
        
        for (String line : lines) {
            line = line.trim();
            
            // 跳过空行
            if (line.isEmpty()) {
                document.add(new Paragraph("\n").setMarginTop(5f));
                continue;
            }
            
            Paragraph paragraph;
            
            // 处理标题（# 开头）
            if (line.startsWith("# ")) {
                String title = line.substring(2).trim();
                paragraph = new Paragraph(title)
                        .setFont(boldFont != null ? boldFont : normalFont)
                        .setFontSize(18)
                        .setFontColor(ColorConstants.BLACK)
                        .setMarginTop(15f)
                        .setMarginBottom(10f);
            }
            // 处理二级标题（## 开头）
            else if (line.startsWith("## ")) {
                String title = line.substring(3).trim();
                paragraph = new Paragraph(title)
                        .setFont(boldFont != null ? boldFont : normalFont)
                        .setFontSize(16)
                        .setFontColor(ColorConstants.BLACK)
                        .setMarginTop(12f)
                        .setMarginBottom(8f);
            }
            // 处理三级标题（### 开头）
            else if (line.startsWith("### ")) {
                String title = line.substring(4).trim();
                paragraph = new Paragraph(title)
                        .setFont(boldFont != null ? boldFont : normalFont)
                        .setFontSize(14)
                        .setFontColor(ColorConstants.BLACK)
                        .setMarginTop(10f)
                        .setMarginBottom(6f);
            }
            // 处理列表项（- 或 * 开头）
            else if (line.startsWith("- ") || line.startsWith("* ")) {
                String listItem = "  • " + line.substring(2).trim();
                paragraph = new Paragraph(listItem)
                        .setFont(normalFont)
                        .setFontSize(12)
                        .setMarginLeft(15f)
                        .setMarginTop(3f);
            }
            // 处理数字列表（1. 2. 等开头）
            else if (line.matches("^\\d+\\.\\s+.*")) {
                paragraph = new Paragraph("  " + line)
                        .setFont(normalFont)
                        .setFontSize(12)
                        .setMarginLeft(15f)
                        .setMarginTop(3f);
            }
            // 处理粗体文本（**text** 格式）
            else if (line.contains("**")) {
                paragraph = new Paragraph()
                        .setFont(normalFont)
                        .setFontSize(12)
                        .setMarginTop(5f);
                        
                String[] parts = line.split("\\*\\*");
                for (int i = 0; i < parts.length; i++) {
                    if (i % 2 == 0) {
                        // 普通文本
                        if (!parts[i].isEmpty()) {
                            paragraph.add(parts[i]);
                        }
                    } else {
                        // 粗体文本 - 使用加粗字体
                        paragraph.add(new com.itextpdf.layout.element.Text(parts[i])
                                .setFont(boldFont != null ? boldFont : normalFont));
                    }
                }
            }
            // 普通段落
            else {
                paragraph = new Paragraph(line)
                        .setFont(normalFont)
                        .setFontSize(12)
                        .setMarginTop(5f);
            }
            
            document.add(paragraph);
        }
    }
}
